/*
 * Jenny Ruppen 09-730-391
 * Sebastien Goldberg 08-914-855
 * Henry Raymond 08-928-061
 * Stefan Mussato 09-752-270
 */
 
package ch.uzh.ifi.sopra.gruppe9.game;

import java.util.ArrayList;
import com.jme3.scene.Node;


/**
 * Window where you can select the buying agents you want to use for an action.
 */
public class BuyingAgentInterface extends Node {
	
	
	/**
	 * List of all registered mouseOver event elements of the game setup screen.
	 */
	private ArrayList<IMouseOverable> mouseOverables = new ArrayList<IMouseOverable>();
	
	
	/**
	 * List of all registered click event elements of the game setup screen.
	 */
	private ArrayList<IClickable> clickables = new ArrayList<IClickable>();

	
	/**
	 * Carry out action button
	 */
	private GuiButton carryOutAction;
	
	
	/**
	 * Cancel button
	 */
	private GuiButton cancel;
	
	
	/**
	 * Allow two buying agents to be used.
	 */
	private boolean allowTwoBuyingAgents;
	
	
	/**
	 * Color constraint of the action location.
	 */
	private BuyingAgent.Color colorConstraint = BuyingAgent.Color.NONE;
	
	
	/**
	 * Selection of the number of buying agents the player wants to use.
	 */
	private GuiSelection number;
	
	
	/**
	 * Selection of the buying agents the player wants to use.
	 */
	private GuiSelection agents;
	
	
	/**
	 * Callback function which is called when the cancel button is clicked.
	 */
	private ICallback cancelAction;
	
	
	/**
	 * Callback function which is called when the carry out action button is clicked.
	 */
	private ICallback carryOutActionAction;
	
	
	/**
	 * List of all buying agents options in the selection
	 */
	private ArrayList<GuiBuyingAgent> playersBuyingAgents;
	
	
	/**
	 * Y coordinate positions / heights of all elements for window with or without number of buying agents choice.
	 */
	private static final int[][] yElementValues = {{205, 260, -999, 255, 385}, {140, 390, 180, 310, 445}};
	
	
	/**
	 * Constructor: Creates geometry.
	 */
	public BuyingAgentInterface(boolean newAllowTwoBuyingAgents, BuyingAgent.Color newColorConstraint) {
		
		this.allowTwoBuyingAgents = newAllowTwoBuyingAgents;
		this.colorConstraint = newColorConstraint;
		
		playersBuyingAgents = GUI.getPanel().getBuyingAgents();
		
		int[] y;
		if(allowTwoBuyingAgents) {
			y = yElementValues[1];
		} else {
			y = yElementValues[0];
		}
		
		GuiWindow window = new GuiWindow(GUI.Offset.SCENE, 59, y[0], 650, y[1], 80);
		this.attachChild(window);
		
		carryOutAction = new GuiButton("Aktion ausf\u00FChren");
		carryOutAction.setPositionSize(GUI.Offset.SCENE, (768 / 2) - 210, y[4], 180, 81);
		carryOutAction.setAction(new ICallback() { 
			public void run() { 
				doCarryOutActionAction();
			}
		});
		this.attachChild(carryOutAction.create());
		carryOutAction.setActive(false);
		
		number = new GuiSelection(false, false);
		agents = new GuiSelection(false, false);
		
		int[] numberOffsetX = {264, 394};
		
		for(int i = 0; i < 2; i++) {
			number.addOption(i + 1, GUI.Offset.SCENE, numberOffsetX[i], y[2], 110, 110, 81);
			
			GuiQuad numberIcon = new GuiQuad();
			numberIcon.setPositionSize(GUI.Offset.SCENE, numberOffsetX[i] + 10, y[2] + 10, 90, 90, 82);
			numberIcon.setMaterial(MaterialManager.getBuyingAgentIcons(), 0.5f * i, 0.0f, 0.5f, 1.0f);
			this.attachChild(numberIcon.create());
		}

		this.attachChild(number);
		number.setAction(new ICallback() {
			public void run() { 
				agents.removeAllValues();
				if(number.getValue() == 1) {
					agents.allowMultipleSelections(false);
					enforceColorConstraint();
				} else {
					agents.allowMultipleSelections(true);
					agents.activateAll();
				}
				checkBuyingAgentSelection();
			}
		});		
		number.setInitialValue(1);
		
		int i = 0;
		for(GuiBuyingAgent playersBuyingAgent : playersBuyingAgents) {
			if(!playersBuyingAgent.isUsed()) {
				agents.addOption(playersBuyingAgent.getId(), GUI.Offset.SCENE, ((768 + 10 - (66 * playersBuyingAgents.size())) / 2) + (i * 66), y[3], 56, 91, 81);
				this.attachChild(playersBuyingAgent.get2D(GUI.Offset.SCENE, ((768 + 10 - (66 * playersBuyingAgents.size())) / 2) + (i * 66) + 8, y[3] + 8, 82));
			} else {
				this.attachChild(new GuiSlot(GUI.Offset.SCENE, ((768 + 10 - (66 * playersBuyingAgents.size())) / 2) + (i * 66), y[3], 56, 91, 81));
			}
			i++;
		}

		this.attachChild(agents);
		agents.setAction(new ICallback() {
			public void run() {
				checkBuyingAgentSelection();
			}
		});	
		enforceColorConstraint();
		
		cancel = new GuiButton("Abbrechen");
		cancel.setPositionSize(GUI.Offset.SCENE, (768 / 2) + 30, y[4], 180, 81);
		cancel.setAction(new ICallback() { 
			public void run() { 
				doCancelAction();
			}
		});
		this.attachChild(cancel.create());
		
		clickables.add(carryOutAction);
		clickables.add(cancel);
		clickables.addAll(number.getClickables());
		clickables.addAll(agents.getClickables());
		GUI.registerClickable(clickables);
		
		mouseOverables.add(carryOutAction);
		mouseOverables.add(cancel);
		mouseOverables.addAll(number.getMouseOverables());
		mouseOverables.addAll(agents.getMouseOverables());
		GUI.registerMouseOverable(mouseOverables);
		
		GUI.getNode().attachChild(this);
	}
	
	
	/**
	 * Deactivate all buying agent options which do not comply with the color constraint.
	 */
	public void enforceColorConstraint() {
		if(colorConstraint != BuyingAgent.Color.NONE) {
			for(GuiBuyingAgent playersBuyingAgent : playersBuyingAgents) {
				if(playersBuyingAgent.getColor() != colorConstraint) {
					agents.deactivate(playersBuyingAgent.getId());
				}
			}
		}
	}
	
	
	/**
	 * Checks if the buying agent selection is legal. If it is it activates the carry out action button.
	 */
	public void checkBuyingAgentSelection() {
		if(number.getValue() == 1 || !allowTwoBuyingAgents) {
			if(agents.getValue() == -1) {
				carryOutAction.setActive(false);
			} else {
				carryOutAction.setActive(true);
			}
		} else {
			if(agents.getValues().size() != 2) {
				carryOutAction.setActive(false);
			} else {
				carryOutAction.setActive(true);
			}
		}
	}
	
	
	/**
	 * Calls callback function when the cancel button is clicked.
	 */
	public void doCancelAction() {
		GUI.unregisterClickable(clickables);
		GUI.unregisterMouseOverable(mouseOverables);
		GUI.getNode().detachChild(this);
		cancelAction.run();
	}
	
	
	/**
	 * Calls callback function when the carry out action button is clicked.
	 */
	public void doCarryOutActionAction() {
		GUI.unregisterClickable(clickables);
		GUI.unregisterMouseOverable(mouseOverables);
		GUI.getNode().detachChild(this);
		carryOutActionAction.run();
	}
	
	
	/**
	 * Sets callback function which is called when the cancel button is clicked.
	 */
	public void setCancelAction(ICallback action) {
		cancelAction = action;
	}
	
	
	/**
	 * Sets callback function which is called when the carry out action button is clicked.
	 */
	public void setCarryOutActionAction(ICallback action) {
		carryOutActionAction = action;
	}
	
	
	/**
	 * Get selected buying agents.
	 */
	public int[] getBuyingAgents() {
		int[] buyingAgentIDs = new int[2];
		if(number.getValue() == 2) {
			buyingAgentIDs[0] = agents.getValues().get(0);
			buyingAgentIDs[1] = agents.getValues().get(1);
		} else {
			buyingAgentIDs[0] = agents.getValue();
			buyingAgentIDs[1] = -1;
		}
		return buyingAgentIDs;
	}
	
}
